package com.joysuch.wwyt.attendant.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.stereotype.Service;
/**
 * @author xsx
 * @version 1.0
 * @date 2023/2/21 15:39
 */

@Service
public class ExcelService {
    public ExcelService() {
    }

    public void writeToExcel(List<Map<String, String>> values, List<String> colsName, OutputStream output, List<String> fieldNames) throws IOException {
//        if (!file.exists()) {
//            file.createNewFile();
//        }

//        FileOutputStream output = new FileOutputStream(file);
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);
        SXSSFSheet sheet = wb.createSheet(String.valueOf("sheet"));
        wb.setSheetName(0, "sheet");
        sheet.trackAllColumnsForAutoSizing();
        sheet.autoSizeColumn(1);
        int rowNum = 0;
        if (colsName.size() > 0) {
            Row row = sheet.createRow(0);
            this.writeColumnName(colsName, row);
            ++rowNum;
        }

        this.writeDataList(values, fieldNames, sheet, rowNum);
        wb.write(output);
        output.close();
    }

    public File writeToExcel(List objs, File file) throws IOException {
        if (!file.exists()) {
            file.createNewFile();
        }

        FileOutputStream output = new FileOutputStream(file);
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);
        SXSSFSheet sheet = wb.createSheet(String.valueOf("sheet"));
        wb.setSheetName(0, "sheet");
        sheet.trackAllColumnsForAutoSizing();
        sheet.autoSizeColumn(1);
        List<String> colsName = new ArrayList();
        List<String> fieldNames = new ArrayList();
        if (objs != null && objs.size() > 0) {
            this.getColAndFields(objs.get(0).getClass(), colsName, fieldNames);
        }

        if (colsName.size() > 0) {
            Row row = sheet.createRow(0);
            this.writeColumnName(colsName, row);
        }

        try {
            this.writeDataList(objs, fieldNames, sheet);
        } catch (NoSuchMethodException var9) {
            var9.printStackTrace();
        } catch (InvocationTargetException var10) {
            var10.printStackTrace();
        } catch (IllegalAccessException var11) {
            var11.printStackTrace();
        }

        wb.write(output);
        output.close();
        return file;
    }

    private void getColAndFields(Class<?> clazz, List<String> colsName, List<String> fieldNames) {
        Field[] var4 = clazz.getDeclaredFields();
        int var5 = var4.length;

        for(int var6 = 0; var6 < var5; ++var6) {
            Field filed = var4[var6];
            ExcelColumn annotation = null;
            if ((annotation = (ExcelColumn)filed.getAnnotation(ExcelColumn.class)) != null) {
                colsName.add(annotation.value());
                if (StringUtils.isEmpty(annotation.aliasMethod())) {
                    fieldNames.add(filed.getName());
                } else {
                    fieldNames.add(annotation.aliasMethod());
                }
            }
        }

        if (clazz.getSuperclass() != null) {
            this.getColAndFields(clazz.getSuperclass(), colsName, fieldNames);
        }

    }

    private void writeDataList(List<Object> values, List<String> fieldNames, Sheet sheet) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        int rowNum = 1;
        Iterator var5 = values.iterator();

        while(var5.hasNext()) {
            Object obj = var5.next();
            Row row = sheet.createRow(rowNum++);

            for(int i = 0; i < fieldNames.size(); ++i) {
                Cell cell = row.createCell(i);
                cell.setCellType(CellType.STRING);
                Object value = obj.getClass().getMethod("get" + this.toUpperFirstChar((String)fieldNames.get(i))).invoke(obj);
                if (value != null) {
                    if (value instanceof Date) {
                        cell.setCellValue(DateFormatUtils.format((Date)value, "yyyy-MM-dd HH:mm:ss"));
                    } else {
                        cell.setCellValue(value.toString());
                    }
                } else {
                    cell.setCellValue("");
                }
            }
        }

    }

    private void writeDataList(List<Map<String, String>> values, List<String> fieldNames, Sheet sheet, int rowNum) {
        for(int i = 0; i < values.size(); ++i) {
            Row row = sheet.createRow(i + rowNum);
            Map<String, String> value = (Map)values.get(i);

            for(int j = 0; j < fieldNames.size(); ++j) {
                Cell cell = row.createCell(j);
//                cell.setCellType(1);
                cell.setCellValue((String)value.get(fieldNames.get(j)));
            }
        }

    }

    private void writeColumnName(List<String> cols, Row row) {
        for(int i = 0; i < cols.size(); ++i) {
            Cell cell = row.createCell(i);
//            cell.setCellType(1);
            cell.setCellValue((String)cols.get(i));
        }

    }

    public String toUpperFirstChar(String string) {
        char[] charArray = string.toCharArray();
        charArray[0] = (char)(charArray[0] - 32);
        return String.valueOf(charArray);
    }
}

